01 - Core/05 - Elements.js (111 lines of code) (raw):
/**
* ELEMENT OBJECT LITERAL
*
* A React component module will no longer export a helper function to create
* virtual elements. Instead it's the responsibility of the consumer to
* efficiently create the virtual element.
*
* Languages that compile to JS can choose to implement the element signature
* in whatever way is idiomatic for that language:
*/
{
type: Button,
props: {
foo: bar,
children: [
{ type: 'span', props: { children: a } },
{ type: 'span', props: { children: b } }
]
},
// optional
key: 'mybutton',
ref: myButtonRef
}
/**
* JSX
*/
<Button foo={bar} key="mybutton" ref={myButtonRef}>
<span>{a}</span>
<span>{b}</span>
</Button>
/**
* PLAIN JS
* __DEV__ MODE
*
* This helper function ensures that your static children don't get the key
* warning. It creates an element for you with the current owner/context.
* The props object is cloned and key/ref moved onto the element.
*/
var _Button = React.createFactory(Button);
var _span = React.createFactory('span');
_Button({ foo: bar, key: 'mybutton', ref: myButtonRef },
_span(null, a),
_span(null, b)
)
/**
* If you use JSX, or can statically analyze that the Factory calls belongs to
* React, then you can chose to opt-in to one of the optimizations modes.
*/
/**
* INLINE
* PRODUCTION MODE
*
* Inline mode simply creates the element objects inline in the code, with
* a lookup for current owner/context as well as resolving default props.
* If defaults aren't known statically, then we create a factory that can help
* assign defaults quickly on the newly created object.
*/
var Button_assignDefaults = React.createDefaultsFactory(Button);
{
type: Button,
props: Button_assignDefaults({
foo: bar,
children: [
{ type: 'span', props: { children: a }, key: null, ref: null, _owner: React._currentOwner, _context: React._currentContext },
{ type: 'span', props: { children: b }, key: null, ref: null, _owner: React._currentOwner, _context: React._currentContext }
]
}),
key: 'mybutton',
ref: myButtonRef,
_owner: React._currentOwner,
_context: React._currentContext
}
/**
* POOLED MODE
*
* Pooled mode doesn't allocate any new objects. Instead it gets mutable objects
* from a pool and reuses them. It overrides the props on the pooled object.
*/
var P1 = React.createElementPool({
type: Button,
key: 'mybutton',
props: {
foo: null,
children: null
}
});
var P2 = React.createElementPool({
type: 'span',
props: {
children: null
}
});
var A2 = React.createArrayPool(2); // Number of items in the array
var t1, t1p, t1c, t2;
(
t1 = P1(),
t1.ref = myButtonRef,
t1p = t1.props,
t1p.foo = bar,
t1p.children = A2(),
t1c = t1p.children,
t1c[0] = (t2 = P2(), t2.props.children = a, t2),
t1c[1] = (t2 = P2(), t2.props.children = b, t2),
t1
)
/**
* NATIVE COMPONENTS
*
* Note that DOM nodes are no longer functions on React.DOM, instead they're
* just strings. JSX will convert any lower-case tag name, or if it has a dash,
* into a string value instead of a scope reference. This makes them compatible
* with custom tags (Web Components).
*/
/**
* TEMPLATE STRINGS
*
* You could create an add-on sugar which uses ES6 template strings to create
* elements. It becomes more palatable if all your components are registered
* through strings.
*/
X`
<my-button foo=${bar} key="mybutton" ref=${myButtonRef}>
<span>${a}</span>
<span>${b}</span>
</my-button>
`